//number
let num: number = 100
let age = 18
let height = 180
//boolean
let flag: boolean = true
flag = false
flag = 20 > 30
//string
let msg: string = "hello world"
msg = "kkk"
//也支持es6的模板字符串
const info = `my age is ${age} and height is ${height}`
console.log(info);

//Array类型
//定义字符串数组
const names: string[] = ["abc", "bac", "cba"]
const names2: Array<string> = ["abc", "bac", "nb"]
names.push("lion")
names2.push("lion2")

//Object类型
const myInfo: object = {
    name: "why",
    age: 18,
    height: 1.88
}
// myInfo = 'codewhy'
// console.log(myInfo[age]);
//但是不能从myinfo中获取数据,也不能设置数据

//Symbod类型 该类型可以让对象可以定义相同的属性名
/*

const person = {
    identity: "程序员",
    identity: "老师"
}

*/
const s1: symbol = Symbol("title")
const s2: symbol = Symbol("title")
const person = {
    [s1]: "程序员",
    [s2]: "老师"
}
console.log(person);

//null和undefined类型
let n: null = null
let u: undefined = undefined

//any类型
let a: any = "why"
a = 123
a = true

const aArray: any[] = ["why", 18, 1.88]


// unknown类型
function foo(): string {
    return 'foo'
}
function bar(): number {
    return 123
}
{   //块级作用域 防止命名冲突
    const flag = true
    let result: unknown
    if (flag) {
        result = foo()
    } else {
        result = bar()

    }
    if (typeof result === "string") {
        console.log(result.length);
    }
}

//never 
//死循环
function loopFun(): never {
    while (true) {
        console.log("123");
    }
}
//抛出异常
function loopErr(): never {
    throw new Error()
}

//never的应用   运用到了联合查询 
//作用:防止用户乱加参数类型,加上不合法的参数会报错,使函数更严谨
function handleMessage(message: number | string) {
    switch (typeof message) {
        case 'string':
            console.log('foo');
            break;
        case 'number':
            console.log('bar');
            break;
        default:
            const check: never = message
    }
}

//tuple类型 元组类型 子元素可以有很多类型的数组
const tInfo: [string, number, number] = ["why", 19, 1.88];
const item1 = tInfo[0]  //why 并且知道类型是string
const item2 = tInfo[1]  //18摈弃知道类型是number类型
{
    //数组与元组的区别
    //数组类型推断不确定
    const info: any[] = ["why", 18, 1.88]
    const item1 = info[0]   //不能确定类型
    //元组类型推断确定
    const tInfo: [string, number, number] = ["why", 19, 1.88];
    const item2 = tInfo[0]//确定string类型
}
//tuple应用场景:可以作为返回值

//函数名(参数):[返回值类型]
//输入一个默认值,返回一个默认值和一个可以操作默认值的函数
//如果返回类型是数组 那么类型是any类型,不太安全
//返回一个对象 {counter：,setCounter：}，键值写死,不具有复用性 
//所以采用元组返回更好
{
    //使用any数据类型
    //缺点:获取的值都是any类型
    function useState(state: any) {
        let currentState = state

        const changeState = (newState: any) => {
            currentState = newState
        }

        const tuple: [any, (newState: any) => void] = [currentState, changeState]

        return tuple
    }
    const [couter, setCounter] = useState(10)
    setCounter(1000)
    const [title, setTitle] = useState('abc')
    setTitle('cbd')
}

//优化,使用泛型

function useState<T>(state: T): [T, (newState: T) => void] {
    let currentState = state
    const changeState = (newState: T) => {

        currentState = newState
    }
    return [currentState, changeState]
}

const [couter, setCounter] = useState(10)
setCounter(1000)

const [title, setTitle] = useState('abc')
setTitle('cbd')


//设置变量为函数类型 不能写function 因为function是关键字 用()=> void

//写法1
const foo1: ()=> void = ()=>{}
//写法2
const foo2: (()=> void) = ()=>{}
//写法3
type MyFunction = ()=> void
const foo3:MyFunction = ()=>{}
//设置函数的返回类型为void
//写法1
function voidFun() {
    console.log(123);
}
//写法2
function voidFun2():void {
    console.log(123);
}

export { }